package com.xiaotu.code.system;

import java.io.Serializable;
import java.util.Date;

import org.springframework.beans.factory.BeanFactory;

/**
 * 任务超类.
 * 
 * 该类包括bean工厂，子类中需要用到其他服务通过bean可以获取到.
 * 
 * <pre>
 * 任务的类型包括同步(sync=true)与非同步的任务（sync=false）：
 * 
 * 1、同步的任务将会排队等待之前的任务执行完成才能获得执行，注意同步任务需保证任务名称唯一；
 * 2、非同步的任务将会直接加入线程池获得执行。
 * </pre>
 * 
 * @author chenxiangrong
 * 
 */
public abstract class BaseTask implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3987730305015757371L;
	// bean工厂，可能任务中需要用到service，通过bean工厂能获取到service
	private BeanFactory beanFactory;
	// 任务名称
	private String taskName;
	/**
	 * 是否同步，如果是，将会根据taskName进行加锁.
	 */
	private boolean sync = false;
	/**
	 * 延迟的秒数.
	 */
	private int delay = 0;
	private Date joinTime = null;

	/**
	 * 默认构造函数，该构造函数用于非同步机制.
	 * 
	 * @param taskName
	 */
	public BaseTask(String taskName) {
		this.taskName = taskName;
		joinTime = new Date();
	}

	/**
	 * 默认构造函数，该构造函数用于同步机制.
	 * 
	 * @param taskName
	 * @param sync
	 *            等于true表示需要同步加锁，false表示可以并发执行.
	 */
	public BaseTask(String taskName, boolean sync) {
		super();
		this.taskName = taskName;
		this.sync = sync;
		joinTime = new Date();
	}

	/**
	 * 默认构造函数，该构造函数用于同步机制.
	 * 
	 * @param taskName
	 * @param sync
	 *            等于true表示需要同步加锁，false表示可以并发执行.
	 * @param delay延迟的秒数
	 */
	public BaseTask(String taskName, int delay, boolean sync) {
		super();
		this.taskName = taskName;
		this.sync = sync;
		this.delay = delay;
		joinTime = new Date();
	}

	/**
	 * 任务执行.
	 */
	public abstract void run() throws ServiceException;

	public BeanFactory getBeanFactory() {
		return beanFactory;
	}

	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	public String getTaskName() {
		return taskName;
	}

	public boolean isSync() {
		return sync;
	}

	public int getDelay() {
		return delay;
	}

	public Date getJoinTime() {
		return joinTime;
	}

	public void setDelay(int delay) {
		this.delay = delay;
	}

}
